package com.edu.aspect;

import com.edu.bean.Book;
import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Date;

//创建 通知类 SpringAOP 的通知 不需要实现 任何接口
public class LogAspect {

    /**
     * 定义 前置通知
     *  配置时 使用
     *   <aop:before method="" pointcut="切点"></aop:before>
     *   前置通知的方法 返回值类型是boolean,可以在方法中 加入一个 参数 JointPoint
     *      了解: 前置通知 正常编写，无法阻止 核心业务代码运行，除非在前置通知中抛出了异常
     */
    public void before(JoinPoint jt) {
//        System.out.println(jt.getSignature().getName());
//        System.out.println(jt.getTarget());
//        System.out.println(jt.getTarget().getClass());
//        System.out.println(jt.getTarget().getClass()+":"+jt.getSignature().getName()+"始执行与"+new Date());
        System.out.println("执行了 前置通知1");
    }

    /**
     * 后置返回通知中 可以使用 JoinPoint jt 去表示 连接点的信息
     * 再加一个Object 类型的参数 表示 业务方法执行完毕之后 返回的结果
     * @param jt
     * @param result
     *  后置通知 无法修改 返回值结果。
     */
    public void afterReturn(JoinPoint jt,Object result){
//        System.out.println(jt.getSignature().getName());
//        System.out.println(result);
//        if(result instanceof Book){
//            Book b = (Book)result;
//            b.setBookId(15);
//            b.setBookName("张三");
//        }
        System.out.println("方法后置返回通知");
    }


    /**
     *  后置异常通知
     *     jt 表示连接点
     *     e 表示业务方法 跑错的那个异常对象
     *     只在连接点方法 发生异常时 才会执行。
     */
    public void afterThrowing(JoinPoint jt,Exception e){
        System.out.println("执行了 后置异常通知");
        System.out.println(e);
    }

    /**
     * 后置通知，不管业务方法执行 有没有发生异常，最终执行的通知
     */
    public void after(JoinPoint jt){
        System.out.println("执行了 后置通知'");
    }

    /**
     * 环绕通知
     */
    public Object around(ProceedingJoinPoint pjt) throws Throwable {
        System.out.println("环绕通知 前置处理");
        Object obj =  pjt.proceed(pjt.getArgs());//原方法的执行
        System.out.println("环绕通知 后置处理");
        return obj;
    }
}
